package com.ljf.finance.domain.service;

import com.ljf.common.domain.service.BasisDomainService;
import com.ljf.common.exception.ServiceException;
import com.ljf.common.utils.CollectionUtil;
import com.ljf.finance.domain.base.FinanceDatAccountReportTypeBaseService;
import com.ljf.finance.domain.repository.FinanceDatVirtualAccountRepository;
import com.ljf.finance.domain.repository.FinanceDatAccountReportDetailRepository;
import com.ljf.finance.domain.repository.FinanceDatAccountReportTypeRepository;
import com.ljf.finance.domain.repository.FinanceRelAccountReportDetailRepository;
import com.ljf.finance.dto.command.FinanceDatAccountReportTypeCommand;
import com.ljf.finance.dto.query.FinanceDatVirtualAccountQuery;
import com.ljf.finance.dto.query.FinanceDatAccountReportDetailQuery;
import com.ljf.finance.dto.query.FinanceDatAccountReportTypeQuery;
import com.ljf.finance.dto.query.FinanceRelAccountReportDetailQuery;
import com.ljf.finance.model.FinanceDatAccountReportType;
import com.ljf.finance.vo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 账户报表类型  领域服务
 *
 * @author LJF
 * @since 2024-12-07
 */
@Component
@AllArgsConstructor
public class FinanceDatAccountReportTypeDomainService extends BasisDomainService<FinanceDatAccountReportTypeRepository, FinanceDatAccountReportTypeQuery, FinanceDatAccountReportTypeVO, FinanceDatAccountReportType, FinanceDatAccountReportTypeCommand> {

    private final FinanceDatAccountReportTypeBaseService baseService;
    private final FinanceDatAccountReportDetailRepository detailRepository;
    private final FinanceRelAccountReportDetailRepository relAccountReportDetailRepository;
    private final FinanceDatVirtualAccountRepository baseVirtualAccountRepository;

    /**
     * 报表数据
     *
     * @param code
     * @return
     * @throws ServiceException
     */
    public FinanceDatAccountReportTypeReportDataVO reportData(String code) throws ServiceException {
        FinanceDatAccountReportTypeVO reportType = repository.selectOne(
                FinanceDatAccountReportTypeQuery.builder().code(code).build(),
                "报表数据校验异常:报表不存在",
                "账户报表类型配置异常:存在多个相同编码"
        );
        List<FinanceDatAccountReportDetailVO> reportDetailList = detailRepository.selectList(
                FinanceDatAccountReportDetailQuery.builder().typeCode(reportType.getCode()).build()
        );
        if (CollectionUtil.isEmpty(reportDetailList)) {
            throw new ServiceException("报表数据配置异常:无明细数据");
        }
        List<String> reportDetailCodeList = reportDetailList.stream()
                .map(FinanceDatAccountReportDetailVO::getCode).distinct().collect(Collectors.toList());
        List<FinanceRelAccountReportDetailVO> relReportDetailList = relAccountReportDetailRepository.selectList(
                FinanceRelAccountReportDetailQuery.builder().detailCodeList(reportDetailCodeList).build()
        );
        if (CollectionUtil.isEmpty(relReportDetailList)) {
            throw new ServiceException("报表数据配置异常:无账户关联关系");
        }
        List<String> accountCodeList = relReportDetailList.stream()
                .map(FinanceRelAccountReportDetailVO::getAccountCode).distinct().collect(Collectors.toList());
        List<FinanceDatVirtualAccountVO> accountList = baseVirtualAccountRepository.selectList(
                FinanceDatVirtualAccountQuery.builder().codeList(accountCodeList).build()
        );
        return baseService.buildReportData(reportType, reportDetailList, relReportDetailList, accountList);
    }

}
